home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / vbcc.lha / vbcc / pasm / support.c < prev    next >
C/C++ Source or Header  |  1998-02-17  |  6KB  |  274 lines

  1. /* $VER: pasm support.c V0.5 (12.10.97)
  2.  *
  3.  * This file is part of pasm, a portable PowerPC assembler.
  4.  * Copyright (c) 1997-98  Frank Wille
  5.  *
  6.  * pasm is freeware and part of the portable and retargetable ANSI C
  7.  * compiler vbcc, copyright (c) 1995-98 by Volker Barthelmann.
  8.  * pasm may be freely redistributed as long as no modifications are
  9.  * made and nothing is charged for it. Non-commercial usage is allowed
  10.  * without any restrictions.
  11.  * EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
  12.  * SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
  13.  *
  14.  *
  15.  * v0.5 (12.10.97) phx
  16.  *      lower_case(), converts a whole string to lower case.
  17.  *      try_mapfile() adds a '\n'-byte to every file it reads.
  18.  * v0.4 (28.06.97) phx
  19.  *      remnode(), removes a node from a list.
  20.  *      mapfile() automatically adds '/' to an include path.
  21.  * v0.3 (26.03.97)
  22.  *      Little to big endian conversion routine - l2bh(), l2bw().
  23.  * v0.2 (25.03.97) phx
  24.  *      Writes ELF object for 32-bit PowerPC big-endian. Either absolute
  25.  *      or ELF output format may be selected. ELF is default for all
  26.  *      currently supported platforms. PPCasm supports nine different
  27.  *      relocation types (there are much more...).
  28.  *      Compiles and works also under NetBSD/amiga (68k).
  29.  *      Changed function declaration to 'new style' in all sources
  30.  *      (to avoid problems with '...' for example).
  31.  *      checkrange() prints a warning message on overflow and no error.
  32.  *      remhead() returns NULL when list is empty.
  33.  * v0.1 (11.03.97) phx
  34.  *      First test version with all PowerPC instructions and most
  35.  *      important directives. Only raw, absolute output.
  36.  *      checkrange() size 3 checks for 26-bit values instead 24-bit.
  37.  *      Do we need a special allocation routine for strings?
  38.  * v0.0 (15.02.97) phx
  39.  *      File created.
  40.  */
  41.  
  42.  
  43. #define SUPPORT_C
  44. #include "ppcasm.h"
  45.  
  46.  
  47. void *alloc(size_t);
  48. void *alloczero(size_t);
  49. char *allocstring(char *);
  50. void initlist(struct list *);
  51. void addtail(struct list *,struct node *);
  52. struct node *remhead(struct list *);
  53. char *mapfile(struct GlobalVars *,char *);
  54. void checkrange(uint32,int,bool);
  55. #ifdef LITTLEENDIAN
  56. uint16 l2bh(uint16);
  57. uint32 l2bw(uint32);
  58. #endif
  59.  
  60. static char *try_mapfile(char *);
  61. static size_t filesize(FILE *,char *);
  62.  
  63.  
  64.  
  65. void *alloc(size_t size)
  66. /* allocate memory and print error message if not enough available */
  67. {
  68.   void *p;
  69.  
  70.   if (!size)
  71.     size = 1;
  72.   if (!(p = malloc(size)))
  73.     error(1);  /* out of memory */
  74.   return (p);
  75. }
  76.  
  77.  
  78. void *alloczero(size_t size)
  79. /* same as alloc() but zeroes the allocated memory */
  80. {
  81.   void *p = alloc(size);
  82.  
  83.   memset(p,0,size);
  84.   return (p);
  85. }
  86.  
  87.  
  88. char *allocstring(char *s)
  89. /* allocate space for a single string */
  90. /* @@@ this should be improved by some kind of string buffer */
  91. {
  92.   char *p = alloc(strlen(s)+1);
  93.  
  94.   strcpy(p,s);
  95.   return (p);
  96. }
  97.  
  98.  
  99. void initlist(struct list *l)
  100. /* initializes a list structure */
  101. {
  102.   l->first = (struct node *)&l->dummy;
  103.   l->dummy = NULL;
  104.   l->last = (struct node *)&l->first;
  105. }
  106.  
  107.  
  108. void addtail(struct list *l,struct node *n)
  109. /* add node as last element of list */
  110. {
  111.   struct node *ln = l->last;
  112.  
  113.   n->next = ln->next;
  114.   ln->next = n;
  115.   n->pred = ln;
  116.   l->last = n;
  117. }
  118.  
  119.  
  120. struct node *remhead(struct list *l)
  121. /* remove first node in list and return a pointer to it */
  122. {
  123.   struct node *n = l->first;
  124.  
  125.   if (n->next) {
  126.     l->first = n->next;
  127.     n->next->pred = n->pred;
  128.     return (n);
  129.   }
  130.   return (NULL);
  131. }
  132.  
  133.  
  134. struct node *remnode(struct node *n)
  135. /* remove a node from a list */
  136. {
  137.   n->next->pred = n->pred;
  138.   n->pred->next = n->next;
  139.   return (n);
  140. }
  141.  
  142.  
  143. char *mapfile(struct GlobalVars *gv,char *name)
  144. /* map a complete file into memory and return its address */
  145. /* the file's length is returned in *(p-sizeof(size_t)) */
  146. /* all defined paths will be searched for the file, before aborting */
  147. {
  148.   char *p;
  149.   int i;
  150.   size_t l;
  151.   char full_name[FNAMEBUFSIZE];
  152.  
  153.   if (p = try_mapfile(name))
  154.     return (p);
  155.   for (i=0; i<MAX_INCPATHS; i++) {
  156.     if (gv->incpaths[i]) {
  157.       strncpy(full_name,gv->incpaths[i],FNAMEBUFSIZE-1);
  158.       l = strlen(gv->incpaths[i]);
  159.       if (l < (FNAMEBUFSIZE-2)) {
  160.         if (full_name[l-1]!='/' && full_name[l-1]!=':')
  161.           full_name[l++] = '/';
  162.         strncat(full_name,name,(FNAMEBUFSIZE-1)-l);
  163.         if (p = try_mapfile(full_name))
  164.           return (p);
  165.       }
  166.     }
  167.   }
  168.   error(6,name);  /* can't open file */
  169. }
  170.  
  171.  
  172. static char *try_mapfile(char *name)
  173. {
  174.   FILE *fp;
  175.   char *p=NULL;
  176.   size_t fsiz;
  177.  
  178.   if (fp = fopen(name,"r")) {
  179.     fsiz = filesize(fp,name);
  180.     p = alloc(fsiz+1+sizeof(size_t));
  181.     *(size_t *)p = fsiz + 1;  /* store file size before the text starts */
  182.     p += sizeof(size_t);
  183.     if (fread(p,1,fsiz,fp) != fsiz) {
  184.       fclose(fp);
  185.       error(5,name);  /* read error */
  186.     }
  187.     fclose(fp);
  188.     *(p+fsiz) = '\n';  /* always have a '\n'-byte at the end */
  189.   }
  190.   return (p);
  191. }
  192.  
  193.  
  194. static size_t filesize(FILE *fp,char *name)
  195. {
  196.   /* somebody knows a better way to determine file size in ANSI C? */
  197.   long oldpos,size;
  198.  
  199.   if ((oldpos = ftell(fp)) >= 0)
  200.     if (fseek(fp,0,SEEK_END) >= 0)
  201.       if ((size = ftell(fp)) >= 0)
  202.         if (fseek(fp,oldpos,SEEK_SET) >= 0)
  203.           return ((size_t)size);
  204.   fclose(fp);
  205.   error(5,name);  /* read error - doesn't return */
  206. }
  207.  
  208.  
  209. void checkrange(uint32 val,int size,bool sign)
  210. /* checks if an integer value is in range, size=3 means 26-bit (B-instr.) */
  211. {
  212.   int sval;
  213.  
  214.   if (sign) {
  215.     sval = (int)val;
  216.     switch (size) {
  217.       case 1:
  218.         if (sval>0x7f || sval<-0x80)
  219.           error(30,8);  /* immediate operand doesn't fit into 8 bits */
  220.         break;
  221.       case 2:
  222.         if (sval>0x7fff || sval<-0x8000)
  223.           error(30,16);
  224.         break;
  225.       case 3:
  226.         if (sval>0x1ffffff || sval<-0x2000000)
  227.           error(30,24);
  228.         break;
  229.     }
  230.   }
  231.   else {
  232.     switch (size) {
  233.       case 1:
  234.         if (val>0xff)
  235.           error(30,8);
  236.         break;
  237.       case 2:
  238.         if (val>0xffff)
  239.           error(30,16);
  240.         break;
  241.       case 3:
  242.         if (val>0x3ffffff)
  243.           error(30,24);
  244.         break;
  245.     }
  246.   }
  247. }
  248.  
  249.  
  250. void lower_case(char *s)
  251. /* convert a whole string to lower case */
  252. {
  253.   unsigned char c;
  254.  
  255.   while (c = (unsigned char)*s)
  256.     *s++ = tolower((int)c);
  257. }
  258.  
  259.  
  260. #ifdef LITTLEENDIAN
  261. uint16 l2bh(uint16 x)
  262. /* little endian half word conversion */
  263. {
  264.   return ECH(x);
  265. }
  266.  
  267.  
  268. uint32 l2bw(uint32 x)
  269. /* little endian word conversion */
  270. {
  271.   return ECW(x);
  272. }
  273. #endif
  274.